<?php

/**
 * PHP for Mysql
 * Mysqli驱动
 */

namespace wtfphp\libs;

class mysql {
    //连接句柄
    private $connection;

    //表前缀
    private $prefix;

    //事务层级
    private $transLevel = 0;

    function __construct($config) {
        $this->con($config);
    }

    function __destruct() {
        mysqli_close($this->connection);
    }

    /**
     * 数据库连接
     * @param $config   array(host,database,user,pwd,charset,prefix)
     */
    function con($config) {
        $this->connection = mysqli_connect($config['host'], $config['user'], $config['pwd'], $config['database']);
        if ($this->connection === false) {
            return false;
        }

        $this->prefix = $config['prefix'];

        $this->charset($config['charset']);
    }

    /**
     * 设置编码
     * @param $encoding
     */
    function charset($encoding) {
        mysqli_query($this->connection, "SET NAMES $encoding");
    }

    /**
     * 捕获错误
     */
    function error() {
        $errArr = array('code' => mysqli_connect_errno(), 'msg' => mysqli_connect_error());
        if (!empty($errArr['msg'])) {
            return $errArr;
        }
        $errArr = array('code' => mysqli_errno($this->connection), 'msg' => mysqli_error($this->connection));
        if (!empty($errArr['msg'])) {
            return $errArr;
        }
        return null;
    }

    /**
     * SQL执行
     * @param $sql      语句
     * @param $resType array：select，pkid：insert，rows：delete/update
     * @param $bind     参数绑定(SELECT * FROM `test` LIMIT ?)
     */
    function sql($sql, $resType = 'array', $bind = array()) {
        //表名前缀=========
        $sql = $this->tablePrefix($sql);
        //参数化执行=========
        if (!empty($bind)) {
            return $this->sqlBind($sql, $bind, $resType);
        }
        //直接执行=========
        $result = mysqli_query($this->connection, $sql);
        //返回
        $return = array();
        switch ($resType) {
            case 'array':
                while ($tmp = mysqli_fetch_assoc($result)) {
                    $return[] = $tmp;
                }
                break;
            case 'pkid':
                $return = mysqli_insert_id($this->connection);
                break;
            case 'rows':
                $return = mysqli_affected_rows($this->connection);
                break;
            default:
                return false;
                break;
        }
        return $return;
    }

    /**
     * SQL执行(参数化)
     */
    private function sqlBind($sql, $bind = array(), $resType = 'array') {
        //执行
        $stmt = mysqli_prepare($this->connection, $sql);
        if ($bind) {
            array_unshift($bind, str_repeat('s', count($bind)));
            array_unshift($bind, $stmt);
            //使用call_user_func_array调用mysqli_stmt_bind_param必须引用传值
            $param_arr = array();
            foreach ($bind as $k => $v) {
                $param_arr[] = &$bind[$k];
            }
            call_user_func_array('mysqli_stmt_bind_param', $param_arr);
        }
        mysqli_stmt_execute($stmt);
        $result = $stmt->get_result();
        //返回
        $return = array();
        switch ($resType) {
            case 'array':
                while ($tmp = mysqli_fetch_assoc($result)) {
                    $return[] = $tmp;
                }
                break;
            case 'pkid':
                $return = mysqli_stmt_insert_id($stmt);
                break;
            case 'rows':
                $return = mysqli_stmt_affected_rows($stmt);
                break;
            default:
                return false;
                break;
        }
        mysqli_stmt_free_result($stmt);
        return $return;
    }

    /**
     * 多语句SQL
     */
    function sqlMulti($sql) {
        return $this->connection->multi_query($sql);
    }

    /**
     * 添加表名前缀
     * @param $sql
     */
    private function tablePrefix($sql) {
        return preg_replace('/`{@(\w+)}`/', '`' . $this->prefix . '${1}`', $sql);
    }

    /**
     * --------------------------------------------------
     * 事务(支持嵌套)
     * --------------------------------------------------
     */
    function transBegin() {
        $this->transLevel = $this->transLevel + 1;
        if ($this->transLevel == 1) {
            return mysqli_autocommit($this->connection, FALSE);
        }
    }

    function transCommit() {
        $this->transLevel = $this->transLevel - 1;
        if ($this->transLevel == 0) {
            return mysqli_commit($this->connection);
        }
    }

    function transBack() {
        $this->transLevel = $this->transLevel - 1;
        if ($this->transLevel == 0) {
            return mysqli_rollback($this->connection);
        }
    }
}